package com.edu.hre.common.cache;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest; 
import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.MemcachedClient;
import net.spy.util.Base64; 
import org.apache.log4j.Logger; 

import com.edu.hre.common.utils.CommonUtils;

public class MemCachedManager {
	
	private static final Logger logger = Logger.getLogger(MemCachedManager.class);
	private static MessageDigest msgDigest = null;
	static {
		try {
			msgDigest = MessageDigest.getInstance("MD5");
		} catch (Exception ex) {
		}
	}
	public static final String BEAN_NAME="memCachedManager";
	private static final String NAMESPACE = "SACHARYA:5d41402abc4b2a76b9719d91101-";
	private static MemcachedClient[] m = null;
	private static final int NUMBER_OF_CLIENT=5;

	public MemCachedManager(String memcachedServer) {
		try {
			m = new MemcachedClient[NUMBER_OF_CLIENT];
			for (int i = 0; i < NUMBER_OF_CLIENT; i++) {
				MemcachedClient c = new MemcachedClient(
						new BinaryConnectionFactory(), AddrUtil
								.getAddresses(memcachedServer));
				m[i] = c;
			}
		} catch (Exception e) {
			logger.error(CommonUtils.getStackTraceException(e)); 
		}
	}

	public void set(String key, int ttl, final Object o) {
		String encodeKey=key;
		try{
			encodeKey=Base64.getInstance().encode(encodeMD5(key).getBytes());
		}catch(Exception exp){
			encodeKey=key;
		}
		try{
			getMemcachedClient().set(NAMESPACE + encodeKey, ttl, o);
		}catch(Exception e){
			logger.error(CommonUtils.getStackTraceException(e)); 
		}
	} 
	
	public Object get(String key) {
		Object o = null;
		String encodeKey=key;
		logger.error("KEY: "+key);
		try{
			logger.error("KEY: "+key);
			encodeKey=Base64.getInstance().encode(encodeMD5(key).getBytes());
		}catch(Exception exp){
			logger.error(exp.getMessage());
			encodeKey=key;
		}
		try{
			o=getMemcachedClient().get(NAMESPACE + encodeKey);
			if (o == null) {
				logger.error("Cache MISS for KEY: " + key);
			} else {
				logger.error("Cache HIT for KEY: " + key);
			}
		}catch(Exception e){
			logger.error(CommonUtils.getStackTraceException(e));
		}
		return o;
	}

	public Object delete(String key) {
		String encodeKey=key;
		try{
			encodeKey=Base64.getInstance().encode(encodeMD5(key).getBytes());
		}catch(Exception exp){
			encodeKey=key;
		}
		try{
			return getMemcachedClient().delete(NAMESPACE + encodeKey);
		}catch(Exception e){
			logger.error(CommonUtils.getStackTraceException(e)); 
		}
		return null;
	}

	public MemcachedClient getMemcachedClient() {
		MemcachedClient c = null;
		try {
			int i = (int) (Math.random() * NUMBER_OF_CLIENT);
			while((i<0)||(i>=NUMBER_OF_CLIENT))
				i = (int) (Math.random() * NUMBER_OF_CLIENT);
			c = m[i];
		} catch (Exception e) {
			logger.error(CommonUtils.getStackTraceException(e)); 
		}
		return c;
	}
	
	private String encodeMD5(String message){
		try {
			return new BigInteger(1, msgDigest.digest((message)
					.getBytes("UTF-8"))).toString(16);
		} catch (UnsupportedEncodingException e) {
			return null;
		} 
	}
}
